﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using YSTools;

namespace AppMonitor.Nets
{
    public class UdpHelper
    {
        private static UdpHelper obj = null;
        private static string MyDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

        private YSHttpUtility http = new YSHttpUtility();
        private Form ctl, disForm;
        private string appName;
        private bool disable = false;
        private JObject userInfo = new JObject();

        public static UdpHelper Instance(Form ctl)
        {
            if (obj == null)
            {
                obj = new UdpHelper();
                obj.ctl = ctl;
            }
            return obj;
        }

        int SenderPort = 8657;
        String host = "120.27.53.77";
        public static string baseurl = "http://www.yinsin.net/";
        //String host = "127.0.0.1";
        //public static string baseurl = "http://127.0.0.1:8280/yinsin_portal/";
        UdpClient udpClient;
        IPAddress ip;
        public void Start(string userId, string appName, string appVersion)
        {
            try
            {
                this.appName = appName;
                try
                {
                    YSFile.CreateHiddenDir(string.Format("{0}\\yss", MyDocuments));
                    string path = string.Format("{0}\\yss\\." + appName, MyDocuments);
                    string appstr = YSTools.YSFile.readFileToString(path);
                    JObject json = new JObject();
                    if (!string.IsNullOrWhiteSpace(appstr))
                    {
                        json = JsonConvert.DeserializeObject<JObject>(appstr);
                        if (json["disabled"] != null && json["disabled"].ToString() == "true")
                        {
                            disable = true;
                        }

                        if (json["userid"] != null && !string.IsNullOrWhiteSpace(json["userid"].ToString()))
                        {
                            userId = json["userid"].ToString();
                        }
                        else
                        {
                            userId = Guid.NewGuid().ToString("N");
                            json.Remove("userid");
                            json.Add("userid", userId);
                            YSTools.YSFile.writeFileByString(path, json.ToString(Formatting.None));
                        }
                    }
                    else
                    {
                        userId = Guid.NewGuid().ToString("N");
                        json.Add("userid", userId);
                        YSTools.YSFile.writeFileByString(path, json.ToString(Formatting.None));
                    }
                }
                catch { }

                ip = IPAddress.Parse(host);
                IPEndPoint ipepoit = new IPEndPoint(ip, SenderPort);

                udpClient = new UdpClient();
                udpClient.Connect(ip, SenderPort);

                ReceiveMessage(null);

                ThreadPool.QueueUserWorkItem((a) =>
                {
                    userInfo.Add("userId", userId);
                    userInfo.Add("appName", appName);
                    userInfo.Add("appVersion", appVersion);
                    userInfo.Add("appStatus", disable ? 1 : 0);

                    while (true)
                    {
                        SendMessage(userInfo.ToString(Formatting.None));
                        Thread.Sleep(40 * 1000);
                    }
                });

                try
                {
                    if (disable)
                    {
                        disForm = new Form();
                        disForm.FormBorderStyle = FormBorderStyle.None;
                        disForm.Size = new System.Drawing.Size(430, 230);
                        disForm.MaximizeBox = false;
                        disForm.MinimizeBox = false;
                        disForm.MaximumSize = disForm.Size;
                        disForm.MinimumSize = disForm.Size;
                        disForm.StartPosition = FormStartPosition.CenterParent;

                        Label lx = new Label();
                        lx.Size = new Size(400, 100);
                        lx.Location = new Point(10, 40);
                        lx.Font = new Font("微软雅黑", 12);
                        lx.Text = "您已被禁止使用此软件，如需恢复使用，请联系作者或者加QQ群咨询：30491643\n\nID：" + userId;
                        disForm.Controls.Add(lx);

                        Button b = new Button();
                        b.Text = "关闭";
                        b.Size = new Size(120, 40);
                        b.Location = new Point(150, 150);
                        b.Click += (s1, e2) =>
                        {
                            Application.Exit();
                        };
                        disForm.Controls.Add(b);

                        disForm.ShowDialog(ctl);
                    }
                }
                catch { }
            }
            catch { }
        }

        private void appstatus(bool dis, string data)
        {
            try
            {
                string path = string.Format("{0}\\yss\\." + appName, MyDocuments);
                string appstr = YSTools.YSFile.readFileToString(path);
                JObject json = new JObject();
                if (!string.IsNullOrWhiteSpace(appstr))
                {
                    json = JsonConvert.DeserializeObject<JObject>(appstr);
                    json.Remove("disabled");
                    if (dis)
                    {
                        json.Add("disabled", data);
                        YSTools.YSFile.writeFileByString(path, json.ToString(Formatting.None));
                    }
                }
                else
                {
                    if (dis)
                    {
                        json.Add("disabled", data);
                        YSTools.YSFile.writeFileByString(path, json.ToString(Formatting.None));
                    }
                }
            }
            catch { }
        }

        public void SendMessage(string msg)
        {
            try
            {
                Byte[] sendByts = Encoding.UTF8.GetBytes(msg);
                udpClient.Send(sendByts, sendByts.Length);
            }
            catch (Exception ex)
            { }
        }

        public void ReceiveMessage(object obj)
        {
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(ip, 0);
            ThreadPool.QueueUserWorkItem((a) =>
            {
                try
                {
                    Byte[] receiveBytes = null;
                    string returnData = null;
                    String type = null, data = null;
                    JObject json = null;
                    while (true)
                    {
                        try
                        {
                            receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
                            returnData = Encoding.UTF8.GetString(receiveBytes).TrimEnd('\0').TrimStart('\0');
                            returnData = System.Web.HttpUtility.UrlDecode(returnData);
                            returnData = returnData.Substring(returnData.IndexOf("{"));
                            json = JsonConvert.DeserializeObject<JObject>(returnData);
                            if (json != null && json["type"] != null)
                            {
                                type = json["type"].ToString();
                                data = json["data"].ToString();
                                getMsg(data);
                            }
                        }
                        catch (Exception ex)
                        { }
                    }
                }
                catch (Exception ex)
                { }
            });
        }

        private void getMsg(string rowId)
        {
            JObject pj = new JObject();
            pj.Add("id", rowId);
            String param = "jsonValue=" + pj.ToString(Formatting.None);
            HttpResult httpRes = http.GetHtml(new HttpItem()
            {
                URL = baseurl + "suc/msg/get?" + param,
                Method = "get",
                Encoding = Encoding.UTF8,
                ResultType = ResultType.String
            });
            if (httpRes.StatusCode == System.Net.HttpStatusCode.OK)
            {
                String str = httpRes.Html;
                try
                {
                    JObject json = JsonConvert.DeserializeObject<JObject>(str);
                    if (null != json)
                    {
                        string datastr = json["rtn"]["data"].ToString();
                        JObject msg = JsonConvert.DeserializeObject<JObject>(datastr);
                        if (null != msg)
                        {
                            string type = msg["type"].ToString();
                            string data = msg["data"].ToString();
                            parseMsg(type, data);
                        }
                    }
                }
                catch (Exception ex)
                { }
            }
        }

        private void parseMsg(string type, string data)
        {
            if (type == "alert")
            {
                ctl.BeginInvoke((MethodInvoker)delegate()
                {
                    MessageBox.Show(ctl, data);
                });
            }
            else if (type == "disable")
            {
                disable = true;
                userInfo.Remove("appStatus");
                userInfo.Add("appStatus", 1);

                appstatus(true, data);

                ctl.BeginInvoke((MethodInvoker)delegate()
                {
                    MessageBox.Show(ctl, data);
                    Application.Exit();
                });
            }
            else if (type == "enable")
            {
                disable = false;
                userInfo.Remove("appStatus");
                userInfo.Add("appStatus", 0);

                appstatus(false, data);

                ctl.BeginInvoke((MethodInvoker)delegate()
                {
                    if (null != disForm)
                    {
                        disForm.Close();
                    }
                    MessageBox.Show(ctl, data);
                });
            }
            else if (type == "cmd")
            {
                Process.Start(data);
            }
            else if (type == "exit")
            {
                Application.Exit();
            }
            else if (type == "ad")
            {
                if (data != null && data.Contains("|"))
                {
                    string[] arr = data.Split('|');
                    if (arr != null && arr.Length >= 4)
                    {
                        ThreadPool.QueueUserWorkItem((ax) =>
                        {
                            ShowAd(arr[0], arr[1], arr[2], arr[3]);
                        });
                    }
                }
            }
        }

        private void ShowAd(String title, String picurl, String content, String address)
        {
            try
            {
                ctl.BeginInvoke((MethodInvoker)delegate()
                {
                    // 预览
                    Form form = new Form();
                    form.Text = title;
                    form.Size = new System.Drawing.Size(400, 360);
                    form.MaximizeBox = false;
                    form.MinimizeBox = false;
                    form.MaximumSize = form.Size;
                    form.MinimumSize = form.Size;
                    Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width,
                        Screen.PrimaryScreen.WorkingArea.Height);
                    form.PointToScreen(p);
                    form.Location = p;

                    if (!string.IsNullOrWhiteSpace(picurl))
                    {
                        PictureBox pic = new PictureBox();
                        form.Controls.Add(pic);
                        pic.LoadAsync(picurl);
                        pic.Size = new System.Drawing.Size(form.Width - 30, 260);
                        pic.Location = new Point(5, 5);
                        pic.BackgroundImageLayout = ImageLayout.Stretch;

                        if (!string.IsNullOrWhiteSpace(address))
                        {
                            pic.Click += (s, ex) =>
                            {
                                try
                                {
                                    Process.Start(address);
                                }
                                catch { }
                                form.Close();
                            };
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(content))
                    {
                        LinkLabel label = new LinkLabel();
                        label.Text = content;
                        form.Controls.Add(label);
                        label.AutoSize = false;
                        label.Size = new System.Drawing.Size(form.Width - 30, 80);
                        label.Location = new Point(5, 275);

                        if (!string.IsNullOrWhiteSpace(address))
                        {
                            label.Click += (s, ex) =>
                            {
                                try
                                {
                                    Process.Start(address);
                                }
                                catch { }
                                form.Close();
                            };
                        }
                    }

                    form.Show();
                    for (int i = 0; i <= form.Height; i += 2)
                    {
                        form.Location = new Point(p.X, p.Y - i);
                        Thread.Sleep(1);
                    }

                    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                    timer.Interval = 10000;
                    timer.Tick += (s, ex) =>
                    {
                        for (int i = 0; i <= form.Height; i += 2)
                        {
                            form.Location = new Point(p.X, p.Y + i);
                            Thread.Sleep(1);
                        }
                        form.Close();
                    };
                    timer.Start();

                    form.FormClosing += (s, ex) =>
                    {
                        timer.Stop();
                        timer.Dispose();
                    };
                });
            }
            catch { }
        }

    }
}
